package com.jie.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jie.constants.RabbitMQConstant;
import com.jie.constants.RedisConstants;
import com.jie.dto.NoticeCountDTO;
import com.jie.dto.NoticeInfoDTO;
import com.jie.dto.OperationLogDTO;
import com.jie.entity.Notice;
import com.jie.entity.OperationLog;
import com.jie.exception.BizException;
import com.jie.filter.SensitiveFilterUtil;
import com.jie.mapper.NoticeMapper;
import com.jie.netty.cline.IMClient;
import com.jie.netty.message.NoticeInfoMessage;
import com.jie.service.INoticeService;
import com.jie.utils.BeanCopyUtils;
import com.jie.utils.StringJointUtils;
import com.jie.utils.UserUtils;
import com.jie.vo.ConditionVO;
import com.jie.vo.NoticeVO;
import com.jie.vo.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static com.jie.constants.CommonConst.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jie
 * @since 2024-07-03
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {

    private final SensitiveFilterUtil sensitiveFilterUtil;
    private final RabbitTemplate rabbitTemplate;
    private final RedisTemplate redisTemplate;

    @Override
    public boolean addNotifyInfo(NoticeVO noticeVO) {
        if (Objects.isNull(noticeVO)){
            throw new BizException("通知公告信息不能为空");
        }
        //敏感词过滤
        noticeVO.setNoticeText(sensitiveFilterUtil.filter(noticeVO.getNoticeText()));
        Notice notice = BeanCopyUtils.copyObject(noticeVO, Notice.class);
        return this.save(notice);
    }

    @Override
    public boolean sendMessage(Integer noticeId) {
        //判断当前notice是否为不存在或者已禁用
        Notice notice = this.baseMapper.selectById(noticeId);
        String username = UserUtils.getLoginUser().getUsername();
        //如果不存在或者不显示就提示当前发送者
        if (Objects.isNull(notice)|| notice.getIsShow().equals(FALSE)){
            throw new BizException("当前通知公告不存在或者已禁用");
        }
        //将这个notice发送给全部人 先推送给mq
        NoticeInfoMessage noticeInfoMessage = new NoticeInfoMessage();
        noticeInfoMessage.setSenderName(username);
        noticeInfoMessage.setData(notice);
        //发送消息到mq中
        rabbitTemplate.convertAndSend(RabbitMQConstant.NOTICE_EXCHANGE, RabbitMQConstant.NOTICE_KEY,noticeInfoMessage);
        log.info("发送公告消息，发送id:{}，内容:{}", username,notice.getNoticeText());
        return false;
    }

    @Override
    public PageResult<NoticeInfoDTO> getNotifyList( ConditionVO conditionVO) {
        Page<Notice> page = new Page<>(conditionVO.getCurrent(), conditionVO.getSize());
        // 查询日志列表
        Page<Notice> noticePage = this.page(page, new LambdaQueryWrapper<Notice>()
                .like(StringUtils.isNotBlank(conditionVO.getKeywords()), Notice::getNoticeTitle, conditionVO.getKeywords())
                .or()
                .like(StringUtils.isNotBlank(conditionVO.getKeywords()), Notice::getNoticeText, conditionVO.getKeywords())
                .orderByDesc(Notice::getId));
        List<NoticeInfoDTO> noticeInfoDTOList = BeanCopyUtils.copyList(noticePage.getRecords(), NoticeInfoDTO.class);
        return new PageResult<>(noticeInfoDTOList,noticeInfoDTOList.size());
    }

    @Override
    public NoticeCountDTO getUnreadNotify() {
        //获取当前用户username
        String username = UserUtils.getLoginUser().getUsername();
        //查询当前用户未读的通知信息条数
        NoticeCountDTO noticeCountDTO = new NoticeCountDTO();
        //用总数-已读的数量
        Integer amount = this.baseMapper.selectCount(null);
        HashOperations hash = redisTemplate.opsForHash();
        Integer readCount =(Integer) hash.get(RedisConstants.NOTICE_LIST, StringJointUtils.addDoubleQuotes(username));
        if (Objects.isNull(readCount)){
            readCount = 0;
        }
        //将未读消息条数置为最大值
        hash.put(RedisConstants.NOTICE_LIST,StringJointUtils.addDoubleQuotes(username),amount);
        //获取到当前用户的条数
        noticeCountDTO.setSystemNoticeCount(amount-readCount);
        return noticeCountDTO;
    }
}
